﻿using System;

namespace Aeon.Emulator.Video
{
    /// <summary>
    /// Represents a point on an emulated buffer from the top-left corner.
    /// </summary>
    public struct Point : IEquatable<Point>
    {
        #region Constructors
        /// <summary>
        /// Initializes a new Point struct.
        /// </summary>
        /// <param name="x">Zero-based distance of the point from the left side of the buffer.</param>
        /// <param name="y">Zero-based distance of the point from the top of the buffer.</param>
        public Point(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
        #endregion

        #region Operators
        public static bool operator ==(Point pointA, Point pointB)
        {
            return pointA.Equals(pointB);
        }
        public static bool operator !=(Point pointA, Point pointB)
        {
            return !pointA.Equals(pointB);
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets or sets the zero-based distance of the point from the left side of the buffer.
        /// </summary>
        public int X
        {
            get { return x; }
            set { x = value; }
        }
        /// <summary>
        /// Gets or sets the zero-based distance of the point from the top of the buffer.
        /// </summary>
        public int Y
        {
            get { return y; }
            set { y = value; }
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Gets a string representation of the Point.
        /// </summary>
        /// <returns>String representation of the Point.</returns>
        public override string ToString()
        {
            return string.Format("{0}, {1}", this.X, this.Y);
        }
        /// <summary>
        /// Tests for equality with another Point.
        /// </summary>
        /// <param name="other">Other Point to test.</param>
        /// <returns>True if points are equal; otherwise false.</returns>
        public bool Equals(Point other)
        {
            return this.X == other.X && this.Y == other.Y;
        }
        /// <summary>
        /// Tests for equality with another object.
        /// </summary>
        /// <param name="obj">Object to test.</param>
        /// <returns>True if objects are equal; otherwise false.</returns>
        public override bool Equals(object obj)
        {
            if(obj is Point)
            {
                Point other = (Point)obj;
                return this.Equals(other);
            }
            else
                return false;
        }
        /// <summary>
        /// Gets a hash code for the point.
        /// </summary>
        /// <returns>Hash code for the point.</returns>
        public override int GetHashCode()
        {
            return this.X.GetHashCode() ^ this.Y.GetHashCode();
        }
        #endregion

        #region Private Fields
        private int x;
        private int y;
        #endregion
    }
}
